<?php

declare(strict_types=1);

namespace Core\Package\ElementPlus\FormCreate\FormItem;

use JetBrains\PhpStorm\ExpectedValues;
use Zms\Exception\FormException;
use Core\Package\ElementPlus\ElementAbstract;

/**
 * 表单抽象类，每个表单都要继承这个类
 * Class FormAbstract
 */
abstract class FormItemAbstract extends ElementAbstract
{
    const VALUE_TYPE_STRING = 'string';
    const VALUE_TYPE_ARRAY = 'array';
    const VALUE_TYPE_NUMBER = 'number';

    /**
     * @var string 字段名
     */
    protected string $_field;


    /**
     * @var string 字段标题
     */
    protected string $_title;

    /**
     * @var string 字段类型
     */
    protected string $_type;

    /**
     * @var mixed 表单值
     */
    protected mixed $_value;


    /**
     * @var array 表单提示
     */
    protected array $_suffix;


    /**
     * 按值显示表单
     * @var array
     */
    protected array $_control = [];


    /**
     * 验证规则
     * @var array
     */
    protected array $_validate = [];


    /**
     * 表单宽度
     * @var array
     */
    protected array $_col = [
        'span' => 24
    ];


    /**
     * @var array 额外属性
     */
    protected array $_props = [
        'disabled' => false,//是否禁用
        'clearable' => false,//是否可清空
    ];


    /**
     * 提示信息
     * @var string
     */
    protected string $_info = '';


    /**
     * 获取指的数据类型
     * @return string
     */
    abstract public function valueType(): string;


    /**
     *
     * @param array $control
     * @return FormItemAbstract
     * @throws FormException
     */
    public function control(array $control): FormItemAbstract
    {
        $controls = [];
        foreach ($control as $item) {
            if (isset($item['value']) && isset($item['rule']) && is_array($item['rule'])) {
                $group = ['value' => $item['value'], 'rule' => []];
                foreach ($item['rule'] as $rule) {
                    if ($rule instanceof ElementAbstract) {
                        $group['rule'][] = $rule->toArray();
                    } else {
                        throw new FormException('不是有效的表单规则');
                    }
                }
                $controls[] = $group;
            } else {
                throw new FormException('表单配置错误');
            }
        }
        $this->_control = $controls;
        return $this;
    }


    /**
     * 设置组件参数
     * @param string $key
     * @param $value
     * @return $this
     */
    public function props(string $key, $value): FormItemAbstract
    {
        $this->_props[$key] = $value;
        return $this;
    }


    /***
     * 设置值
     * @param mixed $value
     * @return $this
     */
    public function value(mixed $value): FormItemAbstract
    {
        $this->_value = $value;
        return $this;
    }


    /***
     * 是否可禁用
     * @param bool $disabled
     * @return $this
     */
    public function disabled(bool $disabled): FormItemAbstract
    {
        return $this->props('disabled', $disabled);
    }


    /**
     * 设置是否可清空表单内容
     * @param bool $clearable
     * @return $this
     */
    public function clearable(bool $clearable): FormItemAbstract
    {
        $this->props('clearable', $clearable);
        return $this;
    }

    /**
     * 设置表单提示语
     * @param $hint
     * @return $this
     * @author 竹林风@875384189 2022/3/16 10:28
     */
    public function hint($hint): FormItemAbstract
    {
        if ($hint) {
            $this->_suffix = [
                'type' => 'p',
                'children' => [$hint],
                'class' => 'app-form-create-hint'
            ];
        } else {
            $this->_suffix = [];
        }
        return $this;
    }


    /**
     * 设置表单宽度
     * @param int $col
     * @return $this
     */
    public function col(int $col): FormItemAbstract
    {
        $this->_col['span'] = $col;
        return $this;
    }


    /**
     * 设置提示信息
     */
    public function info($info): FormItemAbstract
    {
        $this->_info = $info;
        return $this;
    }


    /**
     * 设置标签位置
     */
    public function labelPosition(#[ExpectedValues(['left' | 'right' | 'top'])] string $position): FormItemAbstract
    {
        return $this->props('label-position', $position);
    }


    /**
     * 设置标签宽度
     */
    public function labelWidth(string $width): FormItemAbstract
    {
        return $this->props('label-width', $width);
    }


    /**
     * 设置值
     * @param $value
     * @return FormItemAbstract
     */
    public function setValue($value): FormItemAbstract
    {
        $this->_value = $value;
        return $this;
    }


    /**
     * 项目必填
     */
    public function required($message = true): FormItemAbstract
    {
        if ($message === true) {
            $this->_validate = [['message' => "请输入$this->_title", 'required' => true, 'type' => $this->valueType(), 'trigger' => "change"]];
        } elseif (is_string($message)) {
            $this->_validate = [['message' => $message, 'required' => true, 'type' => $this->valueType(), 'trigger' => "change"]];
        } else {
            $this->_validate = [];
        }
        return $this;
    }


    /**
     * @describe 获取表单字段名
     * @user zlf <zms-pro@qq.com> 2025/3/11
     * @return string
     */
    public function getField(): string
    {
        return $this->_field;
    }
}